﻿using FluentAssertions;
using System.Net;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Http;

namespace System
{
    public class ErrorInfo : RemoteServiceErrorInfo
    {
        public ErrorInfo() { }

        public ErrorInfo(string msg)
        {
            this.Message = msg;
        }

        public HttpStatusCode? HttpStatusCode { get; set; }
        public bool? FriendlyError { get; set; }
    }

    /// <summary>
    /// 接口公共返回值的缩写
    /// </summary>
    public class ResponseEntity : ResponseEntity<object>
    {
        public ResponseEntity() { }
        public ResponseEntity(RemoteServiceErrorInfo error) : base(error) { }
    }

    /// <summary>
    /// 接口公共返回值的缩写
    /// </summary>
    public class ResponseEntity<T> : RemoteServiceErrorResponse, IHasExtraProperties
    {
        [Newtonsoft.Json.JsonIgnore]
        public virtual bool Success => this.Error == null;

        public virtual T Data { get; set; }

        public ExtraPropertyDictionary ExtraProperties { get; } = new ExtraPropertyDictionary();

        /// <summary>
        /// 默认为success，error为null
        /// </summary>
        public ResponseEntity() : base(null) { }
        public ResponseEntity(RemoteServiceErrorInfo error) : base(error) { }

        public virtual ResponseEntity<T> ThrowIfNotSuccess()
        {
            if (this.Error != null)
            {
                throw new BusinessException(message: this.Error.Message, code: this.Error.Code)
                    .WithData("data", this.Data).WithData("error", this.Error);
            }

            return this;
        }

        public virtual ResponseEntity<T> SetSuccess()
        {
            this.Error = null;
            return this;
        }

        public virtual ResponseEntity<T> SetData(T data)
        {
            this.Data = data;
            return this;
        }

        public virtual ResponseEntity<T> SetError(string msg, string code = null, string details = null)
        {
            msg.Should().NotBeNullOrEmpty("错误信息不能为空");

            this.Error = new RemoteServiceErrorInfo(message: msg, code: code, details: details);
            return this;
        }

        public static implicit operator bool(ResponseEntity<T> data) => data.Error == null;
    }
}
